package com.sanbi.shield.client.core.interfaces;

import com.sanbi.shield.client.core.bean.IdempotentRetryItem;
import com.sanbi.shield.server.facade.annotations.ClientIdempotent;

import java.util.List;
import java.util.concurrent.Executor;

/**
 * Client幂等管理器
 *
 * @author XiaoQingqing
 * @since 2024/08/22
 */
public interface ClientIdempotentManager {
    /**
     * 获取执行器
     *
     * @return 执行器
     */
    Executor getExecutor();

    /**
     * 判断是否存在
     *
     * @param methodKey  方法标识
     * @param key        幂等键
     * @param scope      幂等范围
     * @return 判断结果
     */
    boolean exist(String methodKey, String key, ClientIdempotent.Scope scope);

    /**
     * 保存幂等信息
     *
     * @param methodKey   方法标识
     * @param key         幂等键
     * @param scope       幂等范围
     * @param retryTimes  重试次数
     * @param requestInfo 请求信息
     */
    void save(String methodKey, String key, ClientIdempotent.Scope scope, int retryTimes, String requestInfo);

    /**
     * 执行成功
     *
     * @param methodKey  方法标识
     * @param key        幂等键
     * @param scope      幂等范围
     */
    void success(String methodKey, String key, ClientIdempotent.Scope scope);

    /**
     * 执行成功
     *
     * @param methodKey     方法标识
     * @param key           幂等键
     * @param scope         幂等范围
     * @param executedTimes 已执行次数
     * @param ex            异常
     */
    void fail(String methodKey, String key, ClientIdempotent.Scope scope, Integer executedTimes, Throwable ex);

    /**
     * 处理已存在的
     *
     * @param methodKey 方法标识
     * @param key       幂等键
     * @param scope     幂等范围
     * @return 处理结果
     */
    Object handleExisted(String methodKey, String key, ClientIdempotent.Scope scope);

    /**
     * 获取重试定时表达式
     *
     * @return 定时表达式
     */
    String getRetryScheduleCron();

    /**
     * 拉取可以执行的
     *
     * @return 拉取结果
     */
    List<IdempotentRetryItem> pullExecutable();
}
